<template>
  <div class="preview-container">
    <Header :title="fileInfo?.fileName || '文件预览'" show-back />

    <div class="preview-content">
      <!-- 加载状态 -->
      <div v-if="loading" class="loading-state">
        <van-loading type="spinner" size="24" />
        <p>正在加载预览...</p>
      </div>

      <!-- 错误状态 -->
      <div v-else-if="error" class="error-state">
        <van-empty
          image="error"
          :description="error"
        >
          <van-button type="primary" @click="goBack">
            返回
          </van-button>
        </van-empty>
      </div>

      <!-- 不支持预览 -->
      <div v-else-if="!previewInfo?.supportPreview" class="unsupported-state">
        <van-empty
          image="default"
          description="该文件类型不支持预览"
        >
          <van-button type="primary" @click="handleDownload">
            下载文件
          </van-button>
        </van-empty>
      </div>

      <!-- 预览内容 -->
      <div v-else class="preview-wrapper">
        <!-- 图片预览 -->
        <div v-if="previewType === 'image'" class="image-preview">
          <van-image
            :src="previewInfo.previewUrl"
            fit="contain"
            :show-loading="true"
            :show-error="true"
            @click="showImagePreview"
          >
            <template #loading>
              <van-loading type="spinner" size="20" />
            </template>
            <template #error>
              <span>加载失败</span>
            </template>
          </van-image>
        </div>

        <!-- 文本预览 -->
        <div v-else-if="previewType === 'text'" class="text-preview">
          <div class="text-content" v-html="textContent"></div>
        </div>

        <!-- PDF预览 -->
        <div v-else-if="previewType === 'pdf'" class="pdf-preview">
          <iframe
            :src="previewInfo.previewUrl"
            width="100%"
            height="100%"
            frameborder="0"
          ></iframe>
        </div>

        <!-- 音频预览 -->
        <div v-else-if="previewType === 'audio'" class="audio-preview">
          <div class="audio-info">
            <van-icon name="music-o" size="60" color="#1989fa" />
            <h3>{{ fileInfo?.fileName }}</h3>
            <p>{{ formatFileSize(fileInfo?.fileSize || 0) }}</p>
          </div>
          <audio controls class="audio-player">
            <source :src="previewInfo.previewUrl" />
            您的浏览器不支持音频播放。
          </audio>
        </div>

        <!-- 视频预览 -->
        <div v-else-if="previewType === 'video'" class="video-preview">
          <video controls class="video-player">
            <source :src="previewInfo.previewUrl" />
            您的浏览器不支持视频播放。
          </video>
        </div>

        <!-- 其他类型 -->
        <div v-else class="other-preview">
          <van-empty
            image="default"
            description="暂不支持此文件类型的预览"
          >
            <van-button type="primary" @click="handleDownload">
              下载文件
            </van-button>
          </van-empty>
        </div>
      </div>
    </div>

    <!-- 底部操作栏 -->
    <div v-if="previewInfo && previewInfo.supportPreview" class="preview-actions">
      <van-button-group>
        <van-button icon="share-o" @click="handleShare">
          分享
        </van-button>
        <van-button icon="down" @click="handleDownload">
          下载
        </van-button>
        <van-button icon="more-o" @click="showMoreActions = true">
          更多
        </van-button>
      </van-button-group>
    </div>

    <!-- 更多操作面板 -->
    <van-action-sheet
      v-model:show="showMoreActions"
      :actions="moreActions"
      @select="handleMoreAction"
      cancel-text="取消"
    />

    <!-- 图片预览组件 -->
    <van-image-preview
      v-model:show="showImageViewer"
      :images="imageList"
      :start-position="0"
      closeable
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { showToast, showLoadingToast, closeToast, ImagePreview } from 'vant'
import Header from '@/components/Header.vue'
import { generatePreviewUrl, generateDownloadUrl, type PreviewInfoResponse } from '@/api/file'
import { useFileStore } from '@/stores/file'
import type { FileInfo } from '@/api/file'

const router = useRouter()
const route = useRoute()
const fileStore = useFileStore()

// 状态
const loading = ref(true)
const error = ref('')
const fileInfo = ref<FileInfo | null>(null)
const previewInfo = ref<PreviewInfoResponse | null>(null)
const textContent = ref('')
const showMoreActions = ref(false)
const showImageViewer = ref(false)

// 计算属性
const previewType = computed(() => {
  if (!fileInfo.value) return 'unknown'

  const fileName = fileInfo.value.fileName.toLowerCase()
  const ext = fileName.split('.').pop()

  if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext || '')) {
    return 'image'
  }
  if (['txt', 'md', 'json', 'xml', 'csv'].includes(ext || '')) {
    return 'text'
  }
  if (ext === 'pdf') {
    return 'pdf'
  }
  if (['mp3', 'wav', 'aac', 'flac', 'ogg'].includes(ext || '')) {
    return 'audio'
  }
  if (['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm'].includes(ext || '')) {
    return 'video'
  }
  return 'other'
})

const imageList = computed(() => {
  if (previewType.value === 'image' && previewInfo.value) {
    return [previewInfo.value.previewUrl]
  }
  return []
})

const moreActions = [
  { name: '重命名', value: 'rename' },
  { name: '移动', value: 'move' },
  { name: '删除', value: 'delete', color: '#ee0a24' }
]

// 方法
const { formatFileSize } = fileStore

const goBack = () => {
  router.back()
}

const loadFileInfo = async () => {
  const fileId = parseInt(route.params.fileId as string)

  if (!fileId) {
    error.value = '文件ID参数错误'
    loading.value = false
    return
  }

  try {
    loading.value = true

    // 从文件列表中查找文件信息
    const { fileList } = fileStore
    const file = fileList.find(f => f.id === fileId)

    if (file) {
      fileInfo.value = file
      await loadPreviewData(fileId)
    } else {
      // 如果列表中没有，尝试重新获取文件列表
      await fileStore.fetchFileList()
      const refreshedFile = fileStore.fileList.find(f => f.id === fileId)

      if (refreshedFile) {
        fileInfo.value = refreshedFile
        await loadPreviewData(fileId)
      } else {
        error.value = '文件不存在'
      }
    }
  } catch (err: any) {
    error.value = err.message || '加载文件信息失败'
  } finally {
    loading.value = false
  }
}

const loadPreviewData = async (fileId: number) => {
  try {
    const preview = await generatePreviewUrl(fileId)
    previewInfo.value = preview

    // 如果是文本文件，加载文本内容
    if (previewType.value === 'text' && preview.supportPreview) {
      await loadTextContent(preview.previewUrl)
    }
  } catch (err: any) {
    console.error('获取预览信息失败:', err)
    // 不抛出错误，让用户至少可以下载文件
  }
}

const loadTextContent = async (url: string) => {
  try {
    const response = await fetch(url)
    const text = await response.text()
    // 简单的HTML转义
    textContent.value = text
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/\n/g, '<br>')
      .replace(/ /g, '&nbsp;')
  } catch (err) {
    console.error('加载文本内容失败:', err)
    textContent.value = '无法加载文本内容'
  }
}

const showImagePreview = () => {
  if (previewType.value === 'image' && imageList.value.length > 0) {
    ImagePreview({
      images: imageList.value,
      startPosition: 0,
      closeable: true
    })
  }
}

const handleShare = () => {
  if (!fileInfo.value) return
  router.push(`/share/create?fileId=${fileInfo.value.id}`)
}

const handleDownload = async () => {
  if (!fileInfo.value) return

  try {
    showLoadingToast({
      message: '正在生成下载链接...',
      duration: 0
    })

    const downloadInfo = await generateDownloadUrl(fileInfo.value.id)

    closeToast()

    // 创建下载链接
    const link = document.createElement('a')
    link.href = downloadInfo.downloadUrl
    link.download = fileInfo.value.fileName
    link.target = '_blank'

    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

    showToast({
      type: 'success',
      message: '开始下载'
    })
  } catch (error: any) {
    closeToast()
    showToast({
      type: 'fail',
      message: error.message || '下载失败'
    })
  }
}

const handleMoreAction = (action: any) => {
  showMoreActions.value = false

  if (!fileInfo.value) return

  switch (action.value) {
    case 'rename':
      // TODO: 实现重命名功能
      showToast('重命名功能开发中')
      break
    case 'move':
      router.push(`/move?fileId=${fileInfo.value.id}`)
      break
    case 'delete':
      // TODO: 实现删除功能
      showToast('删除功能开发中')
      break
  }
}

onMounted(() => {
  loadFileInfo()
})
</script>

<style scoped>
.preview-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #000;
}

.preview-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.loading-state,
.error-state,
.unsupported-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #f8f8f8;
  color: #969799;
}

.loading-state p {
  margin-top: 12px;
  font-size: 14px;
}

.preview-wrapper {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.image-preview {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
}

.image-preview :deep(.van-image) {
  width: 100%;
  height: 100%;
}

.text-preview {
  width: 100%;
  height: 100%;
  background: #fff;
  overflow-y: auto;
}

.text-content {
  padding: 16px;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;
}

.pdf-preview {
  width: 100%;
  height: 100%;
  background: #fff;
}

.audio-preview {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #f8f8f8;
  padding: 20px;
}

.audio-info {
  text-align: center;
  margin-bottom: 30px;
}

.audio-info h3 {
  margin: 16px 0 8px;
  font-size: 18px;
  color: #323233;
}

.audio-info p {
  margin: 0;
  font-size: 14px;
  color: #969799;
}

.audio-player {
  width: 100%;
  max-width: 300px;
}

.video-preview {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
}

.video-player {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
}

.other-preview {
  width: 100%;
  height: 100%;
  background: #f8f8f8;
  padding: 40px 20px;
}

.preview-actions {
  padding: 12px 16px;
  background: rgba(0, 0, 0, 0.8);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.preview-actions :deep(.van-button-group) {
  width: 100%;
  display: flex;
}

.preview-actions :deep(.van-button) {
  flex: 1;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
}

.preview-actions :deep(.van-button:not(:last-child)) {
  border-right: none;
}

.preview-actions :deep(.van-button:hover) {
  background: rgba(255, 255, 255, 0.1);
}

:deep(.van-empty) {
  padding: 60px 20px;
}
</style>